/*
 * ThermistorTableRow.hpp
 *
 * Copyright 2012 Pieter Agten
 *
 * This file is part of tltgen.
 *
 * tltgen is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * tltgen is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with tltgen.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * @file   ThermistorTableRow.hpp
 * @author Pieter Agten (pieter.agten@gmail.com)
 * @date   30 sep 2012
 */

#ifndef THERMISTORTABLEROW_HPP
#define THERMISTORTABLEROW_HPP

#include <boost/signals2.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/version.hpp>

#include "SerializationException.hpp"

#include "Temperature.hpp"
#include "Resistance.hpp"
#include "Voltage.hpp"
#include "AdcValue.hpp"

namespace tltgen {

  class ThermistorTable;
  class ThermistorTableRow {
  public:
    ThermistorTableRow(ThermistorTable *table);

    enum Column {
      TEMPERATURE = 0,
      RESISTANCE,
      VOLTAGE,
      ADCVALUE,
      NB_COLUMNS
    };

    enum Event {
      COLUMN_CHANGED,
      ROW_CHANGED,
      REMOVE,
    };

    bool hasValue(Column col) const;
    double getValue(Column col) const;
    bool isValidValue(Column col, double value) const;
    void setValue(Column col, double value);
    bool hasValidValue(Column col) const;

    bool hasTemperature() const;
    Temperature getTemperature() const;
    void setTemperature(Temperature t);
    bool isValidTemperature(Temperature t) const;
    bool hasValidTemperature() const;

    bool hasResistance() const;
    Resistance getResistance() const;
    void setResistance(Resistance r);
    bool isValidResistance(Resistance r) const;
    bool hasValidResistance() const;
    
    bool hasVoltage() const;
    Voltage getVoltage() const;
    void setVoltage(Voltage v);
    bool isValidVoltage(Voltage v) const;
    bool hasValidVoltage() const;

    bool hasAdcValue() const;
    int getAdcValue() const;
    void setAdcValue(int adcValue);
    bool isValidAdcValue(int adcValue) const;
    bool hasValidAdcValue() const;

    /*bool hasValue(Column col) const;
    bool hasValidValue(Column col) const;
    double getValue(Column col) const;*/

    void clearTemperature();
    void clearResistanceVoltageAdc();
    void recalculateVoltageAdc();
   
    bool isValid() const;

    ThermistorTable *getThermistorTable() const;
    
    typedef boost::signals2::signal<void (Event, ThermistorTableRow*, Column)> Signal;
    typedef Signal::slot_type Slot;
    boost::signals2::connection connectObserver(const Slot &slot);

  private:
    ThermistorTable *thermistorTable;
    Temperature temperature;
    Resistance resistance;
    Voltage voltage;
    AdcValue adcValue;

    Signal signal;

    friend class ThermistorTable;
    void remove();

    friend class boost::serialization::access;
    template<class Archive> void serialize(Archive & ar, const unsigned int version)
    {
      if (version != 0) {
	throw SerializationException("Unknown version " + 
				     boost::lexical_cast<std::string>(version) + " for ThermistorTableRow.");
      }
      
      ar & this->temperature;
      ar & this->resistance;
      ar & this->voltage;
      ar & this->adcValue;
    }
  };
}

namespace boost {
  namespace serialization {

    template<class Archive>
    inline void save_construct_data(Archive &ar, const tltgen::ThermistorTableRow *r, const unsigned int version)
    {
      if (version != 0) {
        throw tltgen::SerializationException("Unknown version " + lexical_cast<std::string>(version) + 
					     " for saving construct data for ThermistorTableRow.");
      }

      tltgen::ThermistorTable *thermistorTable = r->getThermistorTable();
      ar << thermistorTable;
    }

    template<class Archive>
    inline void load_construct_data(Archive &ar, tltgen::ThermistorTableRow *r, const unsigned int version)
    {
      if (version != 0) {
        throw tltgen::SerializationException("Unknown version " + lexical_cast<std::string>(version) + 
					     " for loading construct data for ThermistorTableRow.");
      }
      
      tltgen::ThermistorTable *thermistorTable;
      ar >> thermistorTable;
      ::new(r) tltgen::ThermistorTableRow(thermistorTable);
    }
  }
}

BOOST_CLASS_VERSION(tltgen::ThermistorTableRow, 0)
//BOOST_CLASS_EXPORT_KEY(tltgen::ThermistorTableRow)

#endif
